package com.itheima.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.itheima.bean.Category;
import com.itheima.bean.Dish;
import com.itheima.bean.Setmeal;
import com.itheima.common.PageParam;
import com.itheima.dao.CategoryDao;
import com.itheima.dto.DishDto;
import com.itheima.exception.CustomException;
import com.itheima.service.CategoryService;
import com.itheima.service.DishService;
import com.itheima.service.SetmealService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Transactional
@Service
public class CategoryServiceImpl implements CategoryService {

    @Autowired
    private CategoryDao categoryDao;

    @Autowired
    private DishService dishService;

    @Autowired
    private SetmealService setmealService;

    /**
     * 根据分类id来查询分类数据
     *
     * @param cid
     * @return
     */
    @Override
    public Category findById(long cid) {
        return categoryDao.selectById(cid);
    }

    /**
     * 添加分类
     * @param category
     * @return 影响行数
     */
    @Override
    public int add(Category category) {
        return categoryDao.insert(category);
    }

    /**
     * 更新分类
     *
     * @param category
     * @return 影响行数
     */
    @Override
    public int update(Category category) {
        return categoryDao.updateById(category);
    }

    /**
     * 查询分类
     *
     * @param type
     * @return 该类型值下的所有分类数据
     */
    @Override
    public List<Category> findByType(Integer type) {
        LambdaQueryWrapper<Category> qw = new LambdaQueryWrapper<>();

        //追加查询的类型条件。

        //后端请求到来的时候，它会传递1 或者 2 过来。
        //前端请求过来的时候，什么都不会传，所以不需要有查询条件，表示想查询所有的分类。
        qw.eq( type != null , Category::getType , type);



        return categoryDao.selectList(qw);
    }

    /**
     * 删除分类
     *   1. 分类不能直接删除，需要判定
     *      1.1 如果该分类是菜品分类，那么需要去查询菜品表，看看是否有这种分类的菜品数据，如果有，禁止删除！
     *      1.2 如果该分类是套餐分类，那么㤇去查询套餐表，看看是否有这种分类的套餐数据，如果有，禁止删除！
     *   2. 当上面的两个步骤都已经检查过了之后，都没有关联的数据，那么可以直接删除掉这个分类！
     *
     * @param id
     * @return 影响行数
     */
    @Override
    public int delete(long id) {
        //0. 由于无法辨别这个id到底是菜品分类的id还是套餐分类的id，所以导致下面要查询两张表，才能判定有没有关联的数据。
        // 其实可以稍微修改一下前端的代码， 不仅把删除的分类id传递过来，顺便也把分类的类型传递过来，然后后续就可以判定
        //分类的类型是什么。如果是菜品分类，就去查看菜品表，如果是套餐分类，就去查看套餐表。这样就高效一些！


        //1. 拿着这个id去查询菜品表，看看有没有菜品是这种分类的
        List<DishDto> dishList = dishService.findByCategoryId(id , null);

        //1.1 如果满足这个条件，即表示该分类是有菜品数据的， 那么禁止删除！
        if(dishList != null && dishList.size() > 0){
            //这里可以直接返回-1，然后在controller 里面判断结果是不是-1， 如果是
            //就告诉前端，有关联的菜品数据，禁止删除！
            //return -1 ;
            throw new CustomException("该分类下有关联菜品数据，禁止删除！");
        }


        //2. 拿着这个id去查询套餐表，看看有没有套餐是这种分类的。
        List<Setmeal> setmealList = setmealService.findByCategoryId(id);

        //2.1 如果满足这个条件，即表示该分类是有套餐数据的， 那么禁止删除！
        if(setmealList != null && setmealList.size() > 0){
            //这里可以直接返回-2，然后在controller 里面判断结果是不是-2， 如果是
            //就告诉前端，有关联的套餐数据，禁止删除！
            //return -2;
            throw new CustomException("该分类下有关联套餐数据，禁止删除！");
        }

        //3. 如果代码来到了这里，即表示上面的两个if判断都不匹配，也就是
        //    这个分类没有任何的菜品数据和套餐数据，可以删除！
        return categoryDao.deleteById(id);
    }

    /**
     * 分页查询
     *
     * @param pageParam
     * @return
     */
    @Override
    public IPage<Category> findPage(PageParam pageParam) {

        //1. 设置查询第几页，每页多少条
        IPage<Category> page = new Page<>(pageParam.getPage() , pageParam.getPageSize());

        //2. 执行查询
        return categoryDao.selectPage(page , null);
    }
}
